using System;
using System.IO;
using System.Runtime.InteropServices;
using daq_test_cs;
using static daq_test_cs.DAQ125Wrapper;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace MultiDeviceDemo
{
    public class DeviceManager
    {
        // 设备信息类
        public class DeviceInfo
        {
            public IntPtr Device { get; set; }
            public IntPtr Socket { get; set; }
            public uint DeviceIndex { get; set; }
            public string DeviceName { get; set; }
            public string DeviceType { get; set; }
            public string HardwareVersion { get; set; }
            public string SoftwareVersion { get; set; }
            public string SerialNumber { get; set; }
            public bool IsConnected { get; set; }
            public float[][] ChannelData { get; set; }
            public List<Task> DataTasks { get; set; }
        }

        private IntPtr _usbServer;
        private List<DeviceInfo> _devices;
        private CancellationTokenSource _cts;

        // 构造函数
        public DeviceManager()
        {
            _devices = new List<DeviceInfo>();
            _cts = new CancellationTokenSource();
        }

        // 初始化USB服务器
        public bool InitializeServer()
        {
            _usbServer = USBServerWrapper.USBServer_New(USBServerWrapper.DeviceType.DeviceType_DAQ125);
            if (_usbServer == IntPtr.Zero)
            {
                Console.WriteLine("USB服务器初始化失败");
                return false;
            }
            
            Console.WriteLine("USB服务器初始化成功");
            
            // 开始搜索设备
            USBServerWrapper.USBServer_StartSearch(_usbServer);
            Console.WriteLine("开始搜索设备...");
            
            // 等待设备被发现
            Thread.Sleep(1000);
            
            return true;
        }

        // 发现所有设备
        public int DiscoverDevices()
        {
            if (_usbServer == IntPtr.Zero)
            {
                Console.WriteLine("USB服务器未初始化");
                return 0;
            }

            uint deviceCount = USBServerWrapper.USBServer_GetDeviceCount(_usbServer);
            Console.WriteLine($"发现 {deviceCount} 个设备");

            if (deviceCount == 0)
            {
                return 0;
            }

            // 清除之前的设备列表
            _devices.Clear();

            // 发现并初始化所有设备
            // 注意：每次获取设备后，总线上的设备指针会减少，所以始终获取第0个设备
            for (uint deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
            {
                var deviceInfo = new DeviceInfo
                {
                    Device = DAQ125Wrapper.DAQ125_New(),
                    DeviceIndex = deviceIndex, // 保留逻辑索引用于标识
                    IsConnected = false
                };

                // 始终获取第0个设备，因为每次获取后设备列表会更新
                IntPtr socket = IntPtr.Zero;
                int maxRetries = 3;
                for (int retryCount = 0; retryCount < maxRetries; retryCount++)
                {
                    socket = USBServerWrapper.USBServer_GetClientByIndex(_usbServer, 0); // 始终获取第0个
                    if (socket != IntPtr.Zero)
                    {
                        break;
                    }
                    
                    Console.WriteLine($"获取设备失败，设备索引: {deviceIndex}，重试 {retryCount + 1}/{maxRetries}");
                    
                    // 重新搜索设备
                    Thread.Sleep(1000);
                }
                
                if (socket == IntPtr.Zero)
                {
                    Console.WriteLine($"获取设备失败，设备索引: {deviceIndex}，已达到最大重试次数");
                    DAQ125Wrapper.DAQ125_Delete(deviceInfo.Device);
                    continue;
                }

                deviceInfo.Socket = socket;

                if (!DAQ125Wrapper.DAQ125_UseBackend(deviceInfo.Device, socket))
                {
                    Console.WriteLine($"无法使用后端，设备索引: {deviceIndex}");
                    DAQ125Wrapper.DAQ125_Delete(deviceInfo.Device);
                    continue;
                }

                if (!DAQ125Wrapper.DAQ125_InitializeDevice(deviceInfo.Device))
                {
                    Console.WriteLine($"初始化设备失败，设备索引: {deviceIndex}");
                    DAQ125Wrapper.DAQ125_Delete(deviceInfo.Device);
                    continue;
                }

                if (!DAQ125Wrapper.DAQ125_ConnectedDevice(deviceInfo.Device))
                {
                    Console.WriteLine($"连接设备失败，设备索引: {deviceIndex}");
                    DAQ125Wrapper.DAQ125_Delete(deviceInfo.Device);
                    continue;
                }

                deviceInfo.IsConnected = true;
                Console.WriteLine($"已连接到设备，设备索引: {deviceIndex}");
                
                // 获取设备信息
                GetDeviceInfo(deviceInfo);
                
                // 添加到设备列表
                _devices.Add(deviceInfo);
            }

            return _devices.Count;
        }

        // 获取设备信息
        private void GetDeviceInfo(DeviceInfo deviceInfo)
        {
            if (!deviceInfo.IsConnected)
                return;

            // 获取设备名称
            System.Text.StringBuilder nameBuffer = new System.Text.StringBuilder(256);
            if (DAQ125Wrapper.DAQ125_SystemOpGetDeviceName(deviceInfo.Device, nameBuffer, 256))
            {
                deviceInfo.DeviceName = nameBuffer.ToString();
                Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 名称: {deviceInfo.DeviceName}");
            }
            else
            {
                Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 获取名称失败");
            }
            
            // 获取设备类别
            if (DAQ125Wrapper.DAQ125_BasicInfoGetDeviceType(deviceInfo.Device))
            {
                System.Text.StringBuilder typeBuffer = new System.Text.StringBuilder(256);
                if (DAQ125Wrapper.DAQ125_GetDeviceType(deviceInfo.Device, typeBuffer, 256))
                {
                    deviceInfo.DeviceType = typeBuffer.ToString();
                    Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 类别: {deviceInfo.DeviceType}");
                }
            }
            
            // 获取硬件版本
            if (DAQ125Wrapper.DAQ125_BasicInfoGetHardwareVersion(deviceInfo.Device))
            {
                System.Text.StringBuilder hwVersionBuffer = new System.Text.StringBuilder(256);
                if (DAQ125Wrapper.DAQ125_GetHardwareVersion(deviceInfo.Device, hwVersionBuffer, 256))
                {
                    deviceInfo.HardwareVersion = hwVersionBuffer.ToString();
                    Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 硬件版本: {deviceInfo.HardwareVersion}");
                }
            }
            
            // 获取软件版本
            if (DAQ125Wrapper.DAQ125_BasicInfoGetSoftwareVersion(deviceInfo.Device))
            {
                System.Text.StringBuilder swVersionBuffer = new System.Text.StringBuilder(256);
                if (DAQ125Wrapper.DAQ125_GetSoftwareVersion(deviceInfo.Device, swVersionBuffer, 256))
                {
                    deviceInfo.SoftwareVersion = swVersionBuffer.ToString();
                    Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 软件版本: {deviceInfo.SoftwareVersion}");
                }
            }
            
            // 获取SN
            if (DAQ125Wrapper.DAQ125_ProductTestGetSN(deviceInfo.Device))
            {
                // 休眠200ms 否则可能导致获取失败
                Thread.Sleep(200);
                
                // 调用GetSN函数获取SN码
                System.Text.StringBuilder snBuffer = new System.Text.StringBuilder(256);
                if (DAQ125Wrapper.DAQ125_GetSN(deviceInfo.Device, snBuffer, 256))
                {
                    deviceInfo.SerialNumber = snBuffer.ToString();
                    Console.WriteLine($"设备[{deviceInfo.DeviceIndex}] 序列号(SN): {deviceInfo.SerialNumber}");
                }
            }
        }

        // 配置所有设备
        public bool ConfigureAllDevices(
            LockzhinerADCTriggerType triggerType = LockzhinerADCTriggerType.RisingEdge,
            LockzhinerADCTriggerMode triggerMode = LockzhinerADCTriggerMode.Common,
            LockzhinerADCChannel triggerChannel = LockzhinerADCChannel.ADCChannelAINNone,
            int triggerLevel = 300,
            LockzhinerADCSampleRate sampleRate = LockzhinerADCSampleRate.ADCSampleRate_800_K,
            LockzhinerADCVoltage voltage = LockzhinerADCVoltage.ADCVoltage_10_V,
            uint triggerLength = 49600,
            uint triggerTimeout = 100,
            byte adcChannel = 0b11111111,
            byte acdcMode = 1)
        {
            bool allConfigured = true;

            foreach (var device in _devices)
            {
                if (!device.IsConnected)
                    continue;

                Console.WriteLine($"配置设备[{device.DeviceIndex}] - {device.DeviceName}");

                // 配置触发模式
                bool result_TriggerType = DAQ125Wrapper.DAQ125_ConfigADCTrigger(
                    device.Device, (int)triggerType, (int)triggerMode, (int)triggerChannel, triggerLevel);
                if (!result_TriggerType)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] ADC触发配置失败");
                    allConfigured = false;
                }

                // 配置采样率
                bool result_SampleRate = DAQ125Wrapper.DAQ125_ConfigADCSampleRate(device.Device, (int)sampleRate);
                if (!result_SampleRate)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 采样率配置失败");
                    allConfigured = false;
                }

                // 配置电压量程
                bool result_ADCVoltage = DAQ125Wrapper.DAQ125_ConfigADCVoltage(device.Device, (int)voltage);
                if (!result_ADCVoltage)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 电压量程配置失败");
                    allConfigured = false;
                }

                // 配置触发长度
                bool result_TriggerLength = DAQ125Wrapper.DAQ125_ConfigADCTriggerLength(device.Device, triggerLength);
                if (!result_TriggerLength)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 触发长度配置失败");
                    allConfigured = false;
                }

                // 配置触发超时
                bool result_TriggerTimeout = DAQ125Wrapper.DAQ125_ConfigTriggerTimeout(device.Device, triggerTimeout);
                if (!result_TriggerTimeout)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 触发超时配置失败");
                    allConfigured = false;
                }

                // 配置ADC通道
                bool result_ADCChannel = DAQ125Wrapper.DAQ125_ConfigADCChannel(device.Device, adcChannel);
                if (!result_ADCChannel)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] ADC通道配置失败");
                    allConfigured = false;
                }

                // 配置ACDC模式
                bool result_ACDCMode = DAQ125Wrapper.DAQ125_ConfigACDC(device.Device, acdcMode);
                if (!result_ACDCMode)
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] ACDC模式配置失败");
                    allConfigured = false;
                }

                // 初始化通道数据数组
                device.ChannelData = new float[8][];
                for (int i = 0; i < 8; i++)
                {
                    device.ChannelData[i] = new float[triggerLength];
                }
                
                // 初始化数据任务列表
                device.DataTasks = new List<Task>();

                Console.WriteLine($"设备[{device.DeviceIndex}] 配置完成");
            }

            return allConfigured;
        }

        // 启动所有设备采集
        public bool StartAllCollection()
        {
            bool allStarted = true;

            // 重置取消令牌源
            _cts = new CancellationTokenSource();

            foreach (var device in _devices)
            {
                if (!device.IsConnected)
                    continue;

                // 开始采集
                if (!DAQ125_StartCollection(device.Device))
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 开始采集失败");
                    allStarted = false;
                    continue;
                }

                Console.WriteLine($"设备[{device.DeviceIndex}] 开始采集成功");

                // 延时100ms
                Thread.Sleep(100);

                // 软件触发
                if (!DAQ125_ConfigADCTriggerSource(device.Device))
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 软件触发失败");
                    allStarted = false;
                    continue;
                }

                Console.WriteLine($"设备[{device.DeviceIndex}] 软件触发成功");
            }

            return allStarted;
        }

        // 启动所有设备的数据读取任务
        public void StartDataReadingTasks(byte adcChannel, uint readSize)
        {
            foreach (var device in _devices)
            {
                if (!device.IsConnected)
                    continue;

                Console.WriteLine($"启动设备[{device.DeviceIndex}] 数据读取任务");

                // 清除之前的任务
                device.DataTasks.Clear();

                // 为每个启用的通道创建一个读取任务
                for (byte channel = 0; channel < 8; channel++)
                {
                    if ((adcChannel & (1 << channel)) != 0) // 检查通道是否启用
                    {
                        byte currentChannel = channel; // 创建局部变量避免闭包问题
                        uint deviceIndex = device.DeviceIndex; // 保存设备索引
                        
                        var task = Task.Run(() =>
                        {
                            bool readSuccess = false;
                            int retryCount = 0;
                            int maxRetries = 10; // 最大重试次数
                            
                            while (!readSuccess && !_cts.Token.IsCancellationRequested && retryCount < maxRetries)
                            {
                                readSuccess = DAQ125_TryReadData_Batch(device.Device, currentChannel, 
                                    device.ChannelData[currentChannel], readSize);
                                
                                if (readSuccess)
                                {
                                    // 计算非零数据的数量
                                    int validDataCount = device.ChannelData[currentChannel].Count(x => x != 0);
                                    
                                    Console.WriteLine($"设备[{deviceIndex}] 通道 {currentChannel + 1} 数据读取成功");
                                    Console.WriteLine($"设备[{deviceIndex}] 通道 {currentChannel + 1} 总数据长度: {readSize}");
                                    Console.WriteLine($"设备[{deviceIndex}] 通道 {currentChannel + 1} 非零数据长度: {validDataCount}");
                                    
                                    // 打印前5个数据点作为示例
                                    Console.WriteLine($"设备[{deviceIndex}] 通道 {currentChannel + 1} 的前5个数据点:");
                                    for (int i = 0; i < Math.Min(5, readSize); i++)
                                    {
                                        Console.WriteLine($"数据点 {i}: {device.ChannelData[currentChannel][i]:F3}V");
                                    }
                                }
                                else
                                {
                                    retryCount++;
                                    Thread.Sleep(100); // 读取失败时等待100ms再试
                                }
                            }
                            
                            if (!readSuccess)
                            {
                                Console.WriteLine($"设备[{deviceIndex}] 通道 {currentChannel + 1} 数据读取失败，已达到最大重试次数");
                            }
                        }, _cts.Token);
                        
                        device.DataTasks.Add(task);
                    }
                }
            }
        }

        // 停止所有设备采集
        public void StopAllCollection()
        {
            // 取消所有数据读取任务
            _cts.Cancel();
            
            // 等待所有任务完成
            foreach (var device in _devices)
            {
                if (device.DataTasks != null && device.DataTasks.Count > 0)
                {
                    try
                    {
                        Task.WaitAll(device.DataTasks.ToArray());
                    }
                    catch (AggregateException)
                    {
                        // 忽略取消导致的异常
                    }
                }
            }
            
            // 停止所有设备采集
            foreach (var device in _devices)
            {
                if (!device.IsConnected)
                    continue;

                if (!DAQ125_StopCollection(device.Device))
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 停止采集失败");
                }
                else
                {
                    Console.WriteLine($"设备[{device.DeviceIndex}] 停止采集成功");
                }
            }
        }


        // 释放资源
        public void Dispose()
        {
            // 停止所有采集
            StopAllCollection();
            
            // 释放所有设备
            foreach (var device in _devices)
            {
                if (device.Device != IntPtr.Zero)
                {
                    DAQ125Wrapper.DAQ125_Delete(device.Device);
                }
            }
            
            // 清空设备列表
            _devices.Clear();
            
            // 释放USB服务器
            if (_usbServer != IntPtr.Zero)
            {
                USBServerWrapper.USBServer_Delete(_usbServer);
                _usbServer = IntPtr.Zero;
            }
        }
    }
} 